package com.wteam.dragon.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wteam.dragon.shop.mapper.*;
import com.wteam.dragon.shop.pojo.bean.Product;
import com.wteam.dragon.shop.pojo.bean.ProductProductAttribute;
import com.wteam.dragon.shop.pojo.bean.SkuStock;
import com.wteam.dragon.shop.pojo.dto.ProductDto;
import com.wteam.dragon.shop.pojo.dto.ProductProductAttributeDto;
import com.wteam.dragon.shop.pojo.dto.QueryProductDto;
import com.wteam.dragon.shop.service.ProductService;
import com.wteam.dragon.system.basebean.bean.ResultMessage;
import com.wteam.dragon.system.util.BeanUtil;
import com.wteam.dragon.system.util.StringUtils;
import com.wteam.dragon.system.util.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author 陈晓辉
 * @Date 2020/7/7 20:22
 */
@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements ProductService {
    private final ProductMapper productMapper;
    private final ProductProductAttributeMapper productProductAttributeMapper;
    private final ProductProductAttributeDtoMapper productProductAttributeDtoMapper;
    private final SkuStockMapper skuStockMapper;
    private final ProductAttributeMapper productAttributeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessage addProduct(ProductDto productDto) {
        //前期准备工作1
        Product product = BeanUtil.from(productDto.getProductVo(), Product.class);
        //1 添加商品
        productMapper.insert(product);
        Long productId = product.getId();
        //前期准备工作2
        List<SkuStock> skuStockList = new ArrayList<>();
        productDto.getSkuStockVoList().forEach(skuStockVo -> {
            SkuStock skuStock = BeanUtil.from(skuStockVo, SkuStock.class);
            skuStock.setProductId(productId);
            skuStockList.add(skuStock);
        });
        List<ProductProductAttribute> productProductAttributeList = new ArrayList<>();
        productDto.getProductProductAttributeVoList().forEach(productProductAttributeVo -> {
            ProductProductAttribute productProductAttribute = BeanUtil.from(productProductAttributeVo, ProductProductAttribute.class);
            productProductAttribute.setProductId(productId);
            productProductAttributeList.add(productProductAttribute);
        });
        //处理SKU库存
        handleSkuStockCode(skuStockList, product.getId());
        //2 添加SKU库存
        skuStockList.forEach(skuStockMapper::insert);
        //3 添加参数
        productProductAttributeList.forEach(productProductAttributeMapper::insert);
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("添加成功");
        return resultMessage;
    }

    /**
     * 处理SKU编号的方法
     */
    private void handleSkuStockCode(List<SkuStock> skuStockList, Long productId) {
        if(CollectionUtils.isEmpty(skuStockList)){
            return;
        }
        for(int i=0; i<skuStockList.size(); i++){
            SkuStock skuStock = skuStockList.get(i);
            if(StringUtils.isEmpty(skuStock.getSkuCode())){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                StringBuilder sb = new StringBuilder();
                //日期
                sb.append(sdf.format(new Date()));
                //四位商品id
                sb.append(String.format("%04d", productId));
                //三位索引id
                sb.append(String.format("%03d", i+1));
                skuStock.setSkuCode(sb.toString());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessage editSkuStock(Long productId, List<SkuStock> skuStockList) {
        ValidationUtil.isNull("productId不能为空", productId);
        skuStockList.forEach(skuStock -> {
            skuStock.setProductId(productId);
        });
        handleUpdateSkuStockList(productId, skuStockList);
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("编辑成功");
        return resultMessage;
    }


    /**
     * 更新SKU库存的方法
     */
    private void handleUpdateSkuStockList(Long productId, List<SkuStock> skuStockList) {
        //当前没有sku直接删除
        QueryWrapper<SkuStock> queryWrapper = new QueryWrapper<>();
        if(CollUtil.isEmpty(skuStockList)){
            queryWrapper.eq("product_id", productId);
            skuStockMapper.delete(queryWrapper);
            return;
        }
        //获取初始sku信息
        queryWrapper.eq("product_id", productId);
        List<SkuStock> oldSkuStockList = skuStockMapper.selectList(queryWrapper);
        //获取新增sku信息
        List<SkuStock> insertSkuList = skuStockList.stream().filter(item->item.getId()==null).collect(Collectors.toList());
        //获取需要更新的sku信息
        List<SkuStock> updateSkuList = skuStockList.stream().filter(item->item.getId()!=null).collect(Collectors.toList());
        List<Long> updateSkuIds = updateSkuList.stream().map(SkuStock::getId).collect(Collectors.toList());
        //获取需要删除的sku信息
        List<SkuStock> removeSkuList = oldSkuStockList.stream().filter(item-> !updateSkuIds.contains(item.getId())).collect(Collectors.toList());
        //处理更新和添加的SKU库存
        handleSkuStockCode(insertSkuList,productId);
        handleSkuStockCode(updateSkuList,productId);

        //新增sku
        if(CollUtil.isNotEmpty(insertSkuList)){
            insertSkuList.forEach(skuStockMapper::insert);
        }
        //删除sku
        if(CollUtil.isNotEmpty(removeSkuList)){
            skuStockMapper.deleteBatchIds(removeSkuList);
        }
        //修改sku
        if(CollUtil.isNotEmpty(updateSkuList)){
            updateSkuList.forEach(skuStockMapper::updateById);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessage delProduct(List<Long> ids) {
        productMapper.deleteBatchIds(ids);
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("删除成功");
        return resultMessage;
    }

    @Override
    public ResultMessage pageProduct(Page<Product> page, QueryProductDto queryProductDto) {
        QueryWrapper<Product>  queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .like(queryProductDto.getName() != null, Product::getName, queryProductDto.getName())
                .like(queryProductDto.getProductSn() != null, Product::getProductSn, queryProductDto.getProductSn())
                .eq(queryProductDto.getProductSortId() != null, Product::getProductSortId, queryProductDto.getProductSortId())
                .eq(queryProductDto.getPublishStatus() != null, Product::getPublishStatus, queryProductDto.getPublishStatus())
                .eq(queryProductDto.getNewStatus() != null, Product::getNewStatus, queryProductDto.getNewStatus())
                .eq(queryProductDto.getRecommendStatus() != null, Product::getRecommendStatus, queryProductDto.getRecommendStatus())
                .orderByAsc(Product::getSort);
        Page<Product> productPage = productMapper.selectPage(page, queryWrapper);
        ResultMessage resultMessage = new ResultMessage();
        Dict resultMap = Dict.create()
                .set("message", "请求成功")
                .set("productPage", productPage);
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setResultParam(resultMap);
        return resultMessage;
    }

    @Override
    public ResultMessage editProduct(ProductDto productDto) {
        //前期准备工作1
        Product product = BeanUtil.from(productDto.getProductVo(), Product.class);
        Long productId = product.getId();
        ValidationUtil.isNull("productId不能为空", productId);
        List<SkuStock> skuStockList = new ArrayList<>();
        productDto.getSkuStockVoList().forEach(skuStockVo -> {
            SkuStock skuStock = BeanUtil.from(skuStockVo, SkuStock.class);
            skuStock.setProductId(productId);
            skuStockList.add(skuStock);
        });
        List<ProductProductAttribute> productProductAttributeList = new ArrayList<>();
        productDto.getProductProductAttributeVoList().forEach(productProductAttributeVo -> {
            ProductProductAttribute productProductAttribute = BeanUtil.from(productProductAttributeVo, ProductProductAttribute.class);
            productProductAttribute.setProductId(productId);
            productProductAttributeList.add(productProductAttribute);
        });
        //更新商品
        productMapper.updateById(product);
        //更新商品SKU库存
        handleUpdateSkuStockList(productId, skuStockList);
        //更新商品参数
        QueryWrapper<ProductProductAttribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProductProductAttribute::getProductId, productId);
        List<Long> attributeIds = productProductAttributeMapper.selectList(queryWrapper).stream().map(ProductProductAttribute::getId).collect(Collectors.toList());
        productProductAttributeMapper.deleteBatchIds(attributeIds);
        productProductAttributeList.forEach(productProductAttributeMapper::insert);
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("编辑成功");
        return resultMessage;
    }

    @Override
    public ResultMessage getSkuStockByProductId(Long productId, String skuCode) {
        QueryWrapper<SkuStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SkuStock::getProductId, productId)
                .like(skuCode != null, SkuStock::getSkuCode, skuCode);
        List<SkuStock> skuStockList = skuStockMapper.selectList(queryWrapper);
        ResultMessage resultMessage = new ResultMessage();
        Dict resultMap = Dict.create()
                .set("message", "请求成功")
                .set("skuStockList", skuStockList);
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setResultParam(resultMap);
        return resultMessage;
    }

    @Override
    public ResultMessage getProduct(Long id) {
        ValidationUtil.isNull("productId不能为空", id);
        //找出商品
        Product product = productMapper.selectById(id);
        //找出SKU库存
        QueryWrapper<SkuStock> skuStockQueryWrapper = new QueryWrapper<>();
        skuStockQueryWrapper.lambda()
                .eq(SkuStock::getProductId, id);
        List<SkuStock> skuStockList = skuStockMapper.selectList(skuStockQueryWrapper);
        //找出商品参数
        QueryWrapper<ProductProductAttributeDto> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ProductProductAttributeDto::getProductId, id);
        List<ProductProductAttributeDto> productProductAttributeDtoList = productProductAttributeDtoMapper.selectList(queryWrapper);
        productProductAttributeDtoList.forEach(dto -> dto.setProductAttribute(productAttributeMapper.selectById(dto.getProductAttributeId())));
        ResultMessage resultMessage = new ResultMessage();
        Dict resultMap = Dict.create()
                .set("message", "请求成功")
                .set("product", product)
                .set("skuStockList", skuStockList)
                .set("productProductAttributeDtoList", productProductAttributeDtoList);
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setResultParam(resultMap);
        return resultMessage;
    }

    @Override
    public ResultMessage editPublishStatus(List<Long> ids, Integer status) {
        if(CollUtil.isNotEmpty(ids)){
            ids.forEach(id -> {
                Product product = new Product();
                product.setId(id);
                product.setPublishStatus(status);
                productMapper.updateById(product);
            });
        }
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("编辑成功");
        return resultMessage;
    }

    @Override
    public ResultMessage editRecommendStatus(List<Long> ids, Integer status) {
        if(CollUtil.isNotEmpty(ids)){
            ids.forEach(id -> {
                Product product = new Product();
                product.setId(id);
                product.setRecommendStatus(status);
                productMapper.updateById(product);
            });
        }
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("编辑成功");
        return resultMessage;
    }

    @Override
    public ResultMessage editNewStatus(List<Long> ids, Integer status) {
        if(CollUtil.isNotEmpty(ids)){
            ids.forEach(id -> {
                Product product = new Product();
                product.setId(id);
                product.setNewStatus(status);
                productMapper.updateById(product);
            });
        }
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("编辑成功");
        return resultMessage;
    }

    @Override
    public ResultMessage pageSimpleProduct(Page<Product> page, String name) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .select(Product::getId, Product::getName, Product::getProductSn, Product::getPrice)
                .like(name != null, Product::getName, name);
        Page<Product> productPage = productMapper.selectPage(page, queryWrapper);
        Dict resultMap = Dict.create()
                .set("message", "请求成功")
                .set("productPage", productPage);
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setResultParam(resultMap);
        return resultMessage;
    }
}
